package com.zjpavt.client.udp.artnet.controlPanel;


import com.zjpavt.client.hal.ArtNetConfig;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;

/**
 * 控制台工厂类
 * @author zyc
 */
@Slf4j
public class ControllerFactory {
    /**
     * 单例
     */
    private static final ControllerFactory INSATANCE = new ControllerFactory();
    /**
     * 设备类型 字符串表示
     */
    private String type;
    /**
     * 取值范围0-255 对应设备的255个域
     */
    private int externstart = 0;

    /**
     * 起始通道的编号 从0开始
     */
    private int beginChannelIndex = 1;

    /**
     * 占据的通道长度
     */
    private int channelLength = 0;

    /**
     * 解析速率 每帧(一个udp数据包)解析一次数据
     */
    private int speed = 1;

    private ControllerFactory() {
    }

    public static ControllerFactory getINSATANCE() {
        return INSATANCE;
    }

    public AbstractArtNetController build() {
        AbstractArtNetController artNetController;
        Assert.assertNotNull("unknow device",type);
        switch (type) {
        case ArtNetConfig.ARTNET_SERVER_OFF:
            artNetController=new WithoutController(0);
            break;
        case ArtNetConfig.ARTNET_SERVER_ON:
            validController();
            artNetController=new MaLightingController(ArtNetConfig.ARTNET_SERVER_ON,externstart,beginChannelIndex,channelLength,speed);
            break;
        case ArtNetConfig.MA_CONTROLLER:
            validController();
            artNetController=new MaLightingController(externstart,beginChannelIndex,channelLength,speed);
            break;
        case ArtNetConfig.SUITE_CONTROLLER:
            validController();
            artNetController=new SuiteOnlineController(externstart,beginChannelIndex,channelLength,speed);
            break;
        default:
            log.error("unknow controller");
            return null;
        }
        return artNetController;
    }

    /**
     * 验证传入参数是否符合要求
     * @return
     */
    private boolean validController() {
//      速度1 每一帧都侦听 最大可设置为20
        Assert.assertTrue(validArtNetParameter(speed,1,20));
//      解析artNet的哪一个域 一般对应第15个字节
        Assert.assertTrue(validArtNetParameter(externstart,0,255));
//      开始通道号 以及通道长度 应该在0-511这个范围内
        Assert.assertTrue(validArtNetParameter(beginChannelIndex, 0, 511));
        Assert.assertTrue(validArtNetParameter(channelLength + beginChannelIndex,0,512));
        return true;
    }

    public void setType(String type) {
        if (ArtNetConfig.getTypeIndex(type) < 0) {
            return;
        }
        this.type = type;
    }

    /**
     *
     * @param externstart 0-255
     */
    public void setExternstart(int externstart) {
        this.externstart = externstart;
    }

    /**
     *
     * @param beginChannelIndex 0-511
     */
    public void setBeginChannelIndex(int beginChannelIndex) {
        this.beginChannelIndex = beginChannelIndex;
    }

    /**
     *
     * @param channelLength 0-512
     */
    public void setChannelLength(int channelLength) {
        this.channelLength = channelLength;
    }

    /**
     * 验证参数范围[min,max]
     * @param parameter
     * @param min
     * @param max
     * @return
     */
    private boolean validArtNetParameter(int parameter, int min, int max) {
        return parameter >= min && parameter <= max;
    }

    /**
     * >=0
     * @param speed
     */
    public void setSpeed(int speed) {
        Assert.assertTrue(speed >= 0);
        this.speed = speed;
    }
}
